<?php
//版本一
/*class Registry{
    private static $instance;
    private $request;

    private function __construct()
    {
    }

    public static function intance(){
        if(!isset(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function getRequest(){
        return $this->request;
    }

    public function setRequest(Request $request){
        $this->request = $request;
    }
}*/

//版本二 基于键和值来存储数据
/*class Registry{
    private static $instance;
    private $values = array();
    private $treeBulider;
    private $conf;

    private function __construct()
    {
    }

    public static function intance(){
        if(!isset(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function get($key){
        if(isset($this->values[$key])){
            return $this->values[$key];
        }
        return null;
    }

    public function set($key, $value){
       $this->values[$key] = $value;
    }

    //可以设置更多的东西
    function treeBulider(){
        if(!isset($this->treeBulider)){
            $this->treeBulider = new TreeBulider();
        }
        return $this->treeBulider;
    }

    function conf(){
        if(!isset($this->conf)){
            $this->conf = new conf();
        }
        return $this->conf;
    }
}*/

//版本三
abstract class Registry{
    abstract  protected function get($key);
    abstract protected function set($key,$val);
}

//请求注册表
class RequestRegistry extends Registry{
    private $values = array();
    private static $instance;

    private function __construct()
    {
    }

    static function instance(){
        if(!isset(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    protected function get($key)
    {
       if(isset($this->values[$key])){
           return $this->values[$key];
       }
        return null;
    }

    protected function set($key, $val)
    {
        $this->values[$key] = $val;
    }

    static function getRequest(){
        return self::$instance->get('request');
    }

    static function setRequest(Request $request){
        self::$instance->set('request',$request);
    }
}

//会话注册表
class SessionRegistry extends Registry{
    private static $instance;

    private function __construct()
    {
        session_start();
    }

    static function instance(){
        if(!isset(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    protected function get($key)
    {
        if(isset($_SESSION[__CLASS__][$key])){
            return $_SESSION[__CLASS__][$key];
        }
        return null;
    }

    protected function set($key, $val)
    {
        $_SESSION[__CLASS__][$key] = $val;
    }

    static function getComplex(){
        return self::$instance->get('complex');
    }

    static function setComplex(Complex $complex){
        self::$instance->set('complex',$complex);
    }
}

class ApplicationRegistry extends Registry{
    private static $instance;
    private $freezedir = 'data';
    private $values = array();
    private $mtimes = array();

    private function __construct()
    {
    }

    static function instance(){
        if(!isset(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    protected function get($key)
    {
        $path = $this->freezedir.DIRECTORY_SEPARATOR.$key;
        if(file_exists($path)){
            clearstatcache();
            $mtime = filemtime($path);
            if(!isset($this->mtimes[$key])){
                $this->mtimes[$key] = 0;
            }
            if($mtime>$this->mtimes[$key]){
                $data = file_get_contents($path);
                $this->mtimes[$key] = $mtime;
                return ($this->values[$key] = unserialize($data));
            }
        }
        if(isset($this->values[$key])){
            return $this->values[$key];
        }
        return null;
    }

    protected function set($key, $val)
    {
        $this->values[$key] = $val;
        $path = $this->freezedir.DIRECTORY_SEPARATOR.$key;
        file_put_contents($path,serialize($val));
        $this->mtimes[$key] = time();
    }

    static function getDSN(){
        self::$instance->get('dsn');
    }

    static function setDSN($dsn){
        self::$instance->set('dsn',$dsn);
    }
}
